Fix push/jmp/call <reg/mem> to check whether the operand is register
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 27 Mar 2007 10:20:55 +0000 (11:20 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 27 Mar 2007 10:20:55 +0000 (11:20 +0100)
or memory when expanding the operand to 8 bytes on x86/64.

Based on original patch by Dexuan Cui <dexuan.cui@intel.com>

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/x86_emulate.c

index aecb36cf7811c284e30321fcb60982bedf5dbc75..aafaed1ee22e92a4f32d177a300b9fff66d9997a 100644 (file)
@@ -1565,8 +1565,10 @@ x86_emulate(
             if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() )
             {
                 dst.bytes = op_bytes = 8;
-                if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
-                                     &dst.val, 8, ctxt)) != 0 )
+                if ( dst.type == OP_REG )
+                    dst.val = *dst.reg;
+                else if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
+                                          &dst.val, 8, ctxt)) != 0 )
                     goto done;
             }
             src.val = _regs.eip;
@@ -1579,8 +1581,10 @@ x86_emulate(
             if ( mode_64bit() && (dst.bytes == 4) )
             {
                 dst.bytes = 8;
-                if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
-                                     &dst.val, 8, ctxt)) != 0 )
+                if ( dst.type == OP_REG )
+                    dst.val = *dst.reg;
+                else if ( (rc = ops->read(dst.mem.seg, dst.mem.off,
+                                          &dst.val, 8, ctxt)) != 0 )
                     goto done;
             }
             if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(dst.bytes),